﻿using System;
using System.Data;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Kenly.DBFramework.Gateway
{
    /// <summary>
    /// 
    /// </summary>
    public class ConfigManager
    {
       
        /// <summary>
        /// 
        /// </summary>
        public static IDictionary<Type, GatewayConfig> Configs
        {
            get;
            private set;
        }

        static ConfigManager()
        {
            ConfigManager.Configs = new Dictionary<Type, GatewayConfig>();
        }

        /// <summary>
        /// 
        /// </summary>
        public static void Clear()
        {
            ConfigManager.Configs.Clear();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static GatewayConfig FindConfig(Type type)
        {
            if (type == null)
            {
                return null;
            }

            if (!ConfigFactory.IsGatewayType(type))
            {
                return null;
            }

            if (!ConfigManager.Configs.ContainsKey(type))
            {
                CreateGatewayConfigsFromFactory(type.Assembly);
            }

            if (!ConfigManager.Configs.ContainsKey(type))
            {
                return null;
            }

            return ConfigManager.Configs[type];
        }

        private static void CreateGatewayConfigsFromFactory(Assembly assembly)
        {
            Type[] allTypes = assembly.GetTypes();
            List<Type> factoryTypes = FindFactoryTypes(allTypes);

            foreach (var factoryType in factoryTypes)
            {
                object instance = Activator.CreateInstance(factoryType);
                IConfigFactory factory = instance as IConfigFactory;
                AddToContainer(factory);
            }
        }

        private static void AddToContainer(IConfigFactory factory)
        {
            foreach (var config in factory.Configs)
            {
                if (!ConfigManager.Configs.ContainsKey(config.Key))
                {
                    ConfigManager.Configs.Add(config);
                }
            }
        }

        private static List<Type> FindFactoryTypes(Type[] allTypes)
        {
            List<Type> factoryTypes = new List<Type>();
            Type factoryInterfaceType = typeof(IConfigFactory);

            foreach (var item in allTypes)
            {
                if (factoryInterfaceType.IsAssignableFrom(item))
                {
                    factoryTypes.Add(item);
                }
            }

            return factoryTypes;
        }
    }
}
